1. 阿里巴巴Java代码开发手册部分注意点笔记

嵩山版

2. 强制

  1. 抽象类名用Abstract开头。

  2. 类名使用首字母大写的驼峰命名风格,但以下情形除外:DO/BO/DTO/VO/AO/PO/UID等。

  3. POJO类的任何布尔类型的变量都不要加is前缀,否则部分框架解析会引起序列化错误。

    个人理解是该布尔类型变量生成的getter方法名会和变量名重复。

    boolean的变量生成方法名的前缀是is_xxx

    Boolean的变量生成方法名的前缀是get_xxx

  4. MySQL中表达是否变量采用is_xxx形式,需要在<resultMap>设置从is_xxx到xxx的映射关系。

  5. 包名单数形式,类名如果有复数含义可以用复数形式。

  6. 所有的复写方法,必须加@Override注解。

  7. 判断对象是否相等应用常量或者有确定的值来调用equals()方法。

    推荐使用JDK7引入的工具类java.util.Objects#equals(Object a, Object b)

  8. 所有整型包装类对象之间值的比较,全部采用equals方法。

    Integer a = 1;
    Integer b = 1;
    System.out.println(a == b);    // true
    System.out.println(a.equals(b));    // true
    
    Integer c = 128;
    Integer d = 128;
    System.out.println(c == d);        // false
    System.out.println(c.equals(d));    // true
    

    原因:Integer类中有IntegerCache静态方法,里面有存放-127-128的cache[],当包装类的Integer值为-127-128,会返回cache中的地址。超出该范围会new对象,从而地址发生不同。

    private static class IntegerCache {
      static final int low = -128;
      static final int high;
      static final Integer cache[];
    
      static {
        // high value may be configured by property
        int h = 127;
    
        //...
    
        // range [-128, 127] must be interned (JLS7 5.1.7)
        assert IntegerCache.high >= 127;
      }
    
      private IntegerCache() {}
    }
    
  9. 任何货币金额,均以最小货币单位且以整型类型来进行存储。

  10. 浮点数之间的等值判断,基本数据类型不可以用==判断,包装数据类型不可以用equals()判断。应该用BigDecimal类的compareTo方法。

    equals方法会比较值和精度,compareTo会忽略精度。

  11. 所有POJO类属性必须使用包装数据类型。

  12. 日期格式化时,传入pattern中表示年份统一使用小写的y。"yyyy-MM-dd HH:mm:ss"

    yyyy表示当天所在的年,YYYY代表的是当天所在的周属于的年份,一周从周日开始,周六结束。只要本周跨年,返回的YYYY就是下一年。

  13. 获取当前毫秒数要用System.currentTimeMillis(),而不是new Date().getTime()。

  14. // 获取今年的天数
    int dayOfThisYear = LocalDate.now().lengthOfYear();
    // 获取指定某年的天数
    LocalDate.of(2021, 8, 2).lengthOfYear();
    
  15. 只要重写equals,就必须重写hashCode。

  16. 判断集合是否为空使用isEmpty(),而不是比较size(),提高效率,可读性好。

  17. 在使用java.util.stream.Collectors类的toMap()方法转为Map集合时,要使用含有参数类型为BinaryOperator, 参数名为mergeFunction的方法。否则当key相同时,会出现异常。

        // ArrayList pairArrayList
    Map<?, ?> map = pairArrayList.stream().collect(
        Collectors.toMap(Pair::getKey, Pair::getValue, (v1, v2) -> v2)
    );
    
  18. 集合转数组的方法,必须使用集合的toArray(T[] array),传入的是类型完全一致,长度为0的空数组。

    ArrayList<String> strings = new ArrayList<>();
    strings.add("123");
    /*
            public <T> T[] toArray(T[] a)
            以正确的顺序返回一个包含此列表中所有元素的数组(从第一个到最后一个元素); 返回的数组的运行时类型是指定数组的运行时类型。 如果列表适合指定的数组,则返回其中。 否则,将为指定数组的运行时类型和此列表的大小分配一个新数组。
            参数
            a - 要存储列表的元素的数组,如果它够大; 否则,为此目的分配相同运行时类型的新数组。
    */
    String[] array = strings.toArray(new String[0]);
    System.out.println(array);
    
  19. 不要再foreach循环里进行元素的remove/add操作。remove元素使用Iterator方式,如果并发操作需要对Iterator对象加锁。

  20. 线程池不允许使用Executors创建,而是通过ThreadPoolExecutor创建,可以规避资源耗尽。

  21. 多线程并行处理定时任务时,Timer运行多个TimeTask时,只要其中之一没有捕获抛出的异常,其他任务便会自动终止运行,使用ScheduledExecutorService则没有这个问题。

  22. switch块中,最后需要有default语句,即使它什么代码都没有。

  23. 当switch括号内的变量类型为String并且此变量为外部参数时,必须先进行null判断。

  24. 高并发场景中,避免使用“等于”判断作为中断或退出的条件。

  25. 所有的枚举类型字段必须要有注释,说明每个数据项的用途。

  26. 服务端发生错误时,返回给前端的响应信息必须包含HTTP状态码、errorCode、errorMessage、用户提示信息四个部分。

  27. 对于需要使用超大整数返回前端的场景,服务端一律使用String字符串类型返回,禁止使用Long类型。

  28. HTTP请求通过URL传递参数时,不能超过2048字节。

  29. 翻页场景中,输入参数小于1,前端返回第一页参数给后端;后段发现用户输入的参数大于总页数,直接返回最后一页。

  30. 服务器内部重定向必须使用forward;外部重定向地址必须使用URL统一代理模块生成,否则会因线上采用HTTPS协议而导致浏览器提示“不安全”,并且还会带来URL维护不一致的问题。

  31. 后台输送给页面的变量必须加$!{var}——中间的感叹号。

    如果var为null或者不存在,那么${var}会直接显示在页面上。

  32. Math.random()返回double类型,取值范围为0<=x<1,可以取到0(注意除0异常),如果想获取整数类型的随机数,不要将x放大10的若干倍然后取整,直接使用Random对象的nextInt或者nextLong方法。

  33. 错误码为字符串类型,共5位,分成两个部分:错误产生来源+四位数字编号。

    错误产生来源分为 A/B/C,A 表示错误来源于用户,比如参数错误,用户安装版本过低,用户支付 超时等问题;B 表示错误来源于当前系统,往往是业务逻辑出错,或程序健壮性差等问题;C 表示错误来源 于第三方服务,比如 CDN 服务出错,消息投递超时等问题;四位数字编号从 0001 到 9999,大类之间的步长间距预留 100

  34. 事务场景中,抛出异常被catch后,如果需要回滚,一定要注意手动回滚事务。

  35. 不要在finally块中使用return。

  36. 所有日志文件至少保存15天,因为有些异常具备以“周”为频次发生的特点。对于 当天日志,以“应用名.log”来保存,保存在/home/admin/应用名/logs/目录下,过往日志 格式为: {logname}.log.{保存日期},日期格式:yyyy-MM-dd

  37. 根据国家法律,网络运行状态、网络安全事件、个人敏感信息操作等相关记录,留存 的日志不少于六个月,并且进行网络多机备份。

  38. 表达是与否概念的字段,必须使用is_xxx 的方式命名,数据类型是 unsigned tinyint(1 表示是,0 表示否)。

  39. 表名不使用复数名词。

  40. 主键索引名为pk_字段名;唯一索引名为uk_字段名;普通索引名则为idx_字段名。

  41. 表必备三字段:id,create_time,update_time。

  42. 页面搜索严禁左模糊或者全模糊,如果需要请走搜索引擎来解决。

    说明:索引文件具有 B-Tree 的最左前缀匹配特性,如果左边的值未确定,那么无法使用此索引。

  43. 不要使用count(列名)或count(常量)来替代count(),count()是SQL92定义的标 准统计行数的语法,跟数据库无关,跟 NULL 和非 NULL 无关。 说明:count(*)会统计值为 NULL 的行,而 count(列名)不会统计此列为 NULL 值的行

  44. 代码中写分页查询逻辑时,若count为0应直接返回,避免执行后面的分页语句。

  45. 数据订正(特别是删除或修改记录操作)时,要先select,避免出现误删除,确认无 误才能执行更新语句。

  46. 对于数据库中表记录的查询和变更,只要涉及多个表,都需要在列名前加表的别名(或 表名)进行限定。 说明:对多表进行查询记录、更新记录、删除记录时,如果对操作列没有限定表的别名(或表名),并且 操作列在多个表中存在时,就会抛异常。

    正例:select t1.name from table_first as t1 , table_second as t2 where t1.id=t2.id;

    反例:在某业务中,由于多表关联查询语句没有加表的别名(或表名)的限制,正常运行两年后,最近在 某个表中增加一个同名字段,在预发布环境做数据库变更后,线上查询语句出现出 1052 异常:Column 'name' in field list is ambiguous。

  47. 在表查询中,一律不要使用 * 作为查询的字段列表,需要哪些字段必须明确写明。

    说明:1)增加查询分析器解析成本。2)增减字段容易与 resultMap 配置不一致。3)无用字段增加网络 消耗,尤其是 text 类型的字段。

  48. sql.xml 配置参数使用:#{},#param# 不要使用${} 此种方式容易出现 SQL 注入。

  49. 更新数据表记录时,必须同时更新记录对应的update_time字段值为当前时间。

  50. 不得使用外键与级联,一切外键概念必须在应用层解决。

Copyright © rootwhois.cn 2021-2022 all right reserved,powered by GitbookFile Modify: 2023-03-05 10:55:52

results matching ""

    No results matching ""